require "net/http"
require 'cgi'

def logger
  ActionController::Base.logger
end

module SM
  class Config
    attr_accessor :server_manager
    class << self
      def get_instance
        @instance ||= Config.new()
        return @instance
      end
    end

    def initialize()
      self.server_manager = CloudSetting.configs['server_manager']['url']
    end
  end

  class Service 
    class SmError < StandardError; end

    class << self
      def config
        SM.config
      end

      def server_manager
        config.server_manager
      end

      def call interface, *args
        escaped_args = []
        params = {}
        params = args.pop if args.last.is_a? Hash
        args.each do |arg|
          escaped_args.push( CGI.escape( arg.to_s ) )
        end
        url = "#{server_manager}/#{interface}/" + escaped_args.join('/')
        remote_call url, params
      end
      
      private
      def remote_call url, params = {}
        response = Net::HTTP.post_form( URI.parse(url), params )
        logger.info "do request #{Time.now} [#{response.class.name}] #{url}|#{params.inspect if params.present?}|#{response.body}"
        if response.is_a?(Net::HTTPSuccess)
          res = ActiveSupport::JSON.decode(response.body)
          if res['status'] == 0
            res['val']
          else
            raise SmError.new(res['err']['msg'])
          end
        else
          raise SmError
        end
        rescue Object => ex
          logger.error "#{Time.now} #{url}|#{params.inspect if params.present?}|#{ex}"
          raise SmError.new(ex)
      end
    end
  end

  def self.config
    SM::Config.get_instance
  end

  def self.do
    SM::Service
  end

end
